// 对axios进行二次封装，使用请求拦截器和相应拦截器
import axios from 'axios'
//引入elementplus消息提示组件
import { ElMessage } from 'element-plus'
//导入小仓库user获取token
import useUserStore from '@/store/module/user'

//利用axios.create方法创建axios实例
const request = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 50000,
})
//数组用于存放请求池
let arrlist: any = []
//为axios实例添加请求和响应拦截器
request.interceptors.request.use(
  (config: any) => {
    //config配置对象，headers属性请求头，给服务器携带公共的参数
    let userStore = useUserStore()
    if (userStore.token) {
      config.headers.token = userStore.token
    }
    //主要用于限制某些接口加载慢用户请求频繁,只保留最后一次相同请求地址
    let list = config.url as string
    if (arrlist && arrlist.length > 0) {
      // 遍历数组检查是否有重复地址请求
      arrlist.forEach((e: any, index: any) => {
        //如果有重复地址请求就取消之前的请求只保留最后一次请求
        if (e['key'].split('/')[3] === list.split('/')[3]) {
          // 从config上使用cancle方法来取消重复的请求
          e['value'].cancel()
          // 撤销请求后从数组删除
          delete arrlist[index]
        }
      })
    }
    // 数据挂载到config上用于在request中检查是否已经请求到数据
    config.requestKey = list
    // new一个axios取消Token方法,把取消请求挂载到config上当发现重复请求时可以直接调用方法取消
    config.cancelToken = new axios.CancelToken((cancel) => {
      config.cancel = cancel
    }) //创建cancelToken
    //将当前请求添加到请求池中
    arrlist.push({
      key: list,
      value: config,
    })
    return Promise.resolve(config)
  },
  (error) => {
    // 请求错误处理
    return Promise.reject(error)
  },
)
request.interceptors.response.use(
  (response: any) => {
    // 数据挂载到config上用于在request中检查是否已经请求到数据
    let requestKey = response.config.requestKey //获取当前请求的Key值
    //如果执行成功-根据key值,从请求池arrlist中移除当前请求config
    arrlist = arrlist.filter((item: any) => item['key'] === requestKey)
    //成功回调，简化data
    return Promise.resolve(response.data)
  },
  (error) => {
    //处理http网络错误
    let message = error.message
    let status = error.response ? error.response.status : 0
    switch (status) {
      case 401:
        message = 'token过期'
        break
      case 403:
        message = '没有权限'
        break
      case 404:
        message = '请求地址错误'
        break
      case 500:
        message = '服务器问题'
        break
      default:
        message = '服务器繁忙,请耐心等待'
        break
    }
    ElMessage({
      type: 'error',
      message: message,
    })
    return Promise.reject(error)
  },
)
export default request
